﻿using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Windows;
using LoginManagerLibrary.Delegates;
using LoginManagerLibrary.Interfaces;

namespace LoginManagerLibrary
{
    public class LoginProvider : ILoginManager, IUserLogin, IResetPassword
    {
        private readonly ILoginDataAccessor _iLoginDataAccessor;

        public LoginProvider(ILoginDataAccessor iLoginDataAccessor)
        {
            _iLoginDataAccessor = iLoginDataAccessor;
        }

        #region User Login

        public event LoginCompleted OnLoginCompletedEvent;

        public UIElement GetUserLoginUI()
        {
            var view = new LoginControl();
            var viewModel = new LoginViewModel(this);
            view.DataContext = viewModel;
            return view;
        }

        private bool ValidateUserNamePassword(string userName, string password, out string errorMessage)
        {
            bool result = true;
            errorMessage = string.Empty;
            string userNameErrorMessage;
            string passwordErrorMesage;

            result &= IsValid(userName, _iLoginDataAccessor.GetUserNameValidationAttributes(), out userNameErrorMessage);
            result &= IsValid(userName, _iLoginDataAccessor.GetPasswordValidationAttributes(), out passwordErrorMesage);

            //Invalid inputs
            if (!result)
            {
                //Both are invalid
                if (!string.IsNullOrEmpty(userNameErrorMessage) && !string.IsNullOrEmpty(passwordErrorMesage))
                {
                    errorMessage = string.Format("{0}{1}{2}", userNameErrorMessage, Environment.NewLine,
                                                 passwordErrorMesage);
                }
                //userName is invalid
                else if (!string.IsNullOrEmpty(userNameErrorMessage))
                {
                    errorMessage = userNameErrorMessage;
                }
                //Password is invalid
                else
                {
                    errorMessage = passwordErrorMesage;
                }
            }

            return result;
        }

        public bool Login(string userName, string password, out string errorMessage)
        {
            return Login(userName, password, true, out errorMessage);
        }

        private bool Login(string userName, string password, bool raiseEvent, out string errorMessage)
        {
            //Validate User inputs
            if (!ValidateUserNamePassword(userName, password, out errorMessage))
            {
                return false;
            }

            bool result = false;
            //Valid User Credential
            if (_iLoginDataAccessor.Login(userName, password))
            {
                result = true;
                //Raise Login Complete event to underlying control
                if (raiseEvent && OnLoginCompletedEvent != null)
                {
                    OnLoginCompletedEvent(userName);
                }
            }
            return result;
        }

        #endregion

        private bool IsValid(object value, ValidationAttribute[] attributes, out string errorMessage)
        {
            errorMessage = null;
            bool result = true;
            if (attributes != null)
            {
                string tempErrorMessage = string.Empty;
                attributes.Where
                    (attribute =>
                         {
                             if (!attribute.IsValid(value))
                             {
                                 tempErrorMessage = string.Format("{0}{1}{2}"
                                                                  , tempErrorMessage, Environment.NewLine,
                                                                  attribute.ErrorMessage);
                                 result = false;
                             }
                             return false;
                         }
                    ).ToArray();
            }
            return result;
        }

        #region Reset Password

        public event ResetPasswordCompleted OnResetPasswordCompletedEvent;
        public UIElement GetResetPasswordUI()
        {
            throw new System.NotImplementedException();
        }

        public bool ResetPassword(string userName, string oldPassword, string newPassword, out string errorMessage)
        {
            bool result = false;
            if (Login(userName, oldPassword,false, out errorMessage))
            {
                //Change Password
                if (!_iLoginDataAccessor.ChangePassword(userName, newPassword))
                {
                    errorMessage = "Unable to change password.Contact administrator";
                }
                else
                {
                    result = true;
                }
            }
            else
            {
                errorMessage = "User name or password is incorrect";
            }
            return result;
        }
        #endregion



    }



}
